import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../widgets/noPage/not_support_page.dart';
import 'context_provider.dart';
import 'handlers/base_handler_list.dart';
import 'handlers/router_handler.dart';

class InitRouter {
  InitRouter._();

  static InitRouter? _instance;

  static InitRouter get instance => _instance ??= InitRouter._();

  final List<Handler> routeHandlers = [];

  late GoRouter _router;

  GoRouter get router => _router;

  /// handle the router config
  Future<void> handle(List<Handler> handlers,
      {String initialLocation = '/',
        List<NavigatorObserver>? observers}) async {
    _router = GoRouter(
        routes: handlers.map((pageItem) {
          return buildGoRoute(pageItem);
        }).toList(),
        navigatorKey: ContextProvider.globalKey,
        initialLocation: initialLocation,
        errorBuilder: (context, state) => const NotSupportPage(),
        observers: observers,
        requestFocus: false,
        debugLogDiagnostics: kDebugMode);
  }
  ///deprecated, should use method [handle]
  @Deprecated('replaced by method [handle]')
  Future<void> initRouterInject(List<BaseHandlerList> handlers,
      {String initialLocation = '/',
        List<NavigatorObserver>? observers}) async {
    return handle(_configureRoutes(handlers), initialLocation: initialLocation, observers: observers);
  }

  ///生成路由表
  List<Handler> _configureRoutes(List<BaseHandlerList> handlerList) {
    List<Handler> listHandler = [];
    if (handlerList.isNotEmpty) {
      for (var value in handlerList) {
        List<Handler> childHandlers = value.exportHandlerList();
        if (childHandlers.isNotEmpty) {
          listHandler.addAll(childHandlers);
        }
      }
    }
    return listHandler;
  }

  GoRoute buildGoRoute(Handler pageItem) {
    if (pageItem.animationType == AnimationType.slideLeft) {
      return GoRoute(
        path: pageItem.routerKey.routePath,
        name: pageItem.routerKey.routeName,
        redirect: pageItem.redirect,
        builder:(context, state) => pageItem.handlerFunc?.call(context, state) ?? const SizedBox(),
        routes: pageItem.childHandlers.map((childPage) {
          return GoRoute(
            path: childPage.routerKey.routePath,
            name: childPage.routerKey.routeName,
            redirect: childPage.redirect,
            builder: (context, state) => pageItem.handlerFunc?.call(context, state) ?? const SizedBox()
          );
        }).toList());
    } else {
      return GoRoute(
        path: pageItem.routerKey.routePath,
        name: pageItem.routerKey.routeName,
        redirect: pageItem.redirect,
        pageBuilder: (context, state) => _routerPageBuilder(context, state, pageItem),
        routes: pageItem.childHandlers.map((childPage) {
          return GoRoute(
            path: childPage.routerKey.routePath,
            name: childPage.routerKey.routeName,
            redirect: childPage.redirect,
            pageBuilder: (context, state) => _routerPageBuilder(context, state, pageItem),
          );
        }).toList());
    }
  }

  Page<dynamic> _routerPageBuilder(context, state, Handler handler) {
    return CustomTransitionPage(
      key: state.pageKey,
      transitionDuration: _transitionDurationTime(handler.animationType),
      reverseTransitionDuration: _transitionDurationTime(handler.animationType),
      child: handler.handlerFunc?.call(context, state) ?? const SizedBox(),
      transitionsBuilder: handler.animationType.getAnimation,
      opaque: handler.opaque,
    );
  }

  Duration _transitionDurationTime(AnimationType type) {
    if (type == AnimationType.none) {
      return const Duration(milliseconds: 0);
    } else {
      return const Duration(milliseconds: 300);
    }
  }

}
